home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / smaltalk / manchest.lha / MANCHESTER / manchester / 4.1 / BetterRandom.st < prev    next >
Text File  |  1993-07-24  |  4KB  |  136 lines

  1. "    NAME        BetterRandom
  2.     AUTHOR        Bernard Horan <bernard@is.morgan.com>
  3.     CONTRIBUTOR    Bernard Horan <bernard@is.morgan.com>
  4.     FUNCTION     Improved Random number interface
  5.     ST-VERSIONS    4.1
  6.     PREREQUISITES     
  7.     CONFLICTS     
  8.     DISTRIBUTION    global
  9.     VERSION        2.0
  10.     DATE        March 1993
  11.     SUMMARY        I've never been happy with the implmentation
  12. of Random, since I don't see why it's the clients responsibility to
  13. transform a 'raw' float between 0 and 1 to a number (or element) from
  14. some specified range.
  15.  
  16. The other approach is to send a message to an instance of Random, asking for
  17. an element within a range, providing some parameters as arguments to the
  18. message.
  19.  
  20. Personally, I feel that it's the responsibility of the instance of
  21. Random to simply provide the another random element when asked for its
  22. "next", and that the instance of Random should be created with the
  23. appropriate parameters so it can do so.
  24.  
  25. In this light, I've implemented a subclass of Random, called BetterRandom,
  26. it follows below. Let me know what you think of it.
  27.  
  28. Bern"
  29.  
  30. 'From Objectworks\Smalltalk(R), Release 4.1 of 15 April 1992
  31. ENVY/Developer R1.40 of 21 August 1992 on 1 March 1993 at 11:48:01 am'!
  32.  
  33. Random subclass: #BetterRandom
  34.     instanceVariableNames: 'transformBlock '
  35.     classVariableNames: ''
  36.     poolDictionaries: ''
  37.     category: 'New-Random'!
  38.  
  39.  
  40. !BetterRandom methodsFor: 'accessing'!
  41.  
  42. next
  43.     "return the next random number, having transformed it by the block"
  44.     ^transformBlock value: super next! !
  45.  
  46. !BetterRandom methodsFor: 'private'!
  47.  
  48. initialize
  49.     "emulate my super"
  50.     self transformBlock: [:x | x]!
  51.  
  52. transformBlock: aBlock
  53.     "aBlock should be a one-argument block -- the argument is the 'raw' random number"
  54.     transformBlock := aBlock! !
  55. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  56.  
  57. BetterRandom class
  58.     instanceVariableNames: ''!
  59.  
  60.  
  61. !BetterRandom class methodsFor: 'examples'!
  62.  
  63. exampleCollection1
  64.     "Interval as argument"
  65.     "BetterRandom exampleCollection1"
  66.  
  67.     | rand |
  68.     rand := BetterRandom fromCollection: (1 to: 13 by: 0.7).
  69.     10 timesRepeat: [Transcript show: rand next printString; cr]!
  70.  
  71. exampleCollection2
  72.     "SequenceableCollection as argument"
  73.     "BetterRandom exampleCollection2"
  74.  
  75.     | rand |
  76.     rand := BetterRandom fromCollection: ColorValue constantNames.
  77.     10 timesRepeat: [Transcript show: rand next printString; cr]!
  78.  
  79. exampleCollection3
  80.     "Set as argument"
  81.     "BetterRandom exampleCollection3"
  82.  
  83.     | rand |
  84.     rand := BetterRandom fromCollection: Object subclasses.
  85.     10 timesRepeat: [Transcript show: rand next printString; cr]!
  86.  
  87. exampleFloat
  88.     "BetterRandom exampleFloat"
  89.     | rand |
  90.     rand := BetterRandom floatBetween: 4 and: 13.
  91.     10 timesRepeat: [Transcript show: rand next printString; cr]!
  92.  
  93. exampleInteger
  94.     "BetterRandom exampleInteger"
  95.     | rand |
  96.     rand := BetterRandom integerBetween: 4 and: 13.
  97.     10 timesRepeat: [Transcript show: rand next printString; cr]! !
  98.  
  99. !BetterRandom class methodsFor: 'instance creation'!
  100.  
  101. floatBetween: start and: stop 
  102.     | size |
  103.     size := stop - start.
  104.     size > 0 ifFalse: [^self error: 'non-positive range'].
  105.     ^self fromBlock: [:x | x * size + start ]!
  106.  
  107. fromBlock: aBlock
  108.     "aBlock should be a one-argument block -- the argument is the 'raw' random number"
  109.     ^self new transformBlock: aBlock!
  110.  
  111. fromCollection: aCollection 
  112.     "Create an instance of me which will return a random element from the 
  113.     argument"
  114.  
  115.     | size aSequenceableCollection |
  116.     aSequenceableCollection := aCollection isSequenceable ifFalse: [aCollection asOrderedCollection]
  117.                 ifTrue: [aCollection].
  118.     size := aSequenceableCollection size.
  119.     size > 0 ifFalse: [^self error: 'Empty collection'].
  120.     ^self
  121.         fromBlock: 
  122.             [:x | 
  123.             | index |
  124.             index := (x * size + 1) truncated.
  125.             aSequenceableCollection at: index]!
  126.  
  127. integerBetween: start and: stop 
  128.     | size |
  129.     size := stop - start.
  130.     size > 0 ifFalse: [^self error: 'non-positive range'].
  131.     ^self fromBlock: [:x | (x * size + start) truncated]!
  132.  
  133. new
  134.     ^super new initialize! !
  135.  
  136.